//******************************************************************************
//this code is protected by the GNU affero GPLv3
//author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
//                        <digital.ragnarok AT gmail dot com>
//******************************************************************************
#include "globals.h"

static void release(struct client *c,s32 registry_map_slot)
{
    c->objs[registry_map_slot].state=CLIENT_OBJ_INVALID;
    registry_gbl_unref(&registry[c->objs[registry_map_slot].map.name]);
}

s8 registry_map_new_visible(struct client *c,s32 name,u32 id)
{
  s8 r=LWL_OK;
  s32 registry_map_slot=CLIENT_FIRST_VALID_ID;

  while(1){
    if(registry_map_slot==CLIENT_OBJS_MAX) break;

    if(c->objs[registry_map_slot].state&CLIENT_OBJ_INVALID){
      c->objs[registry_map_slot].state=CLIENT_OBJ_REGISTRY_MAP
                                                            |CLIENT_OBJ_VISIBLE;
      c->objs[registry_map_slot].release=release;
      c->objs[registry_map_slot].id=id;
      c->objs[registry_map_slot].n=1;//the wire has a reference on it
      c->objs[registry_map_slot].map.name=name;
      goto exit;
    }
    ++registry_map_slot;
  }

  PERR("client(%d):registry_map_create:no room for new object\n",c->so);
  r=LWL_ERR;

exit:
  return r;
}

s8 registry_map_close(struct client *c,s32 registry_map_slot)
{
  s32 n=client_obj_unref(c,registry_map_slot);
  if(!n) c->objs[registry_map_slot].state&=~CLIENT_OBJ_VISIBLE;
  return wl_display_ev_delete_id(c,c->objs[registry_map_slot].id);
}

s8 registry_map_req(struct client *c,s32 registry_map_slot,struct msg *m)
{
  s8 r=LWL_OK;
  s32 name=c->objs[registry_map_slot].map.name;

  switch(registry[name].itf){
  case WL_DISPLAY:
    r=wl_display_req(c,m);//registry singleton, map cannot be closed
    break;
  case WL_REGISTRY:
    r=wl_registry_req(c,m);//registry singleton, map cannot be closed
    break;
  case WL_SHM:
    r=wl_shm_req(c,m);//registry singleton, map cannot be closed
    break;
  case WL_COMPOSITOR:
    r=wl_compositor_req(c,m);//registry singleton, map cannot be closed
    break;
  case WL_DATA_DEVICE_MANAGER:
    r=wl_data_device_manager_req(c,m);//registry singleton, map cannot be closed
    break;
  case WL_SHELL:
    r=wl_shell_req(c,m);//registry singleton, map cannot be closed
    break;
  case WL_SEAT:
    //registry singleton only if default seat(seat0), map can be closed
    r=wl_seat_req(c,registry_map_slot,m);
    break;
  default:
    PERR("client(%d):fatal:registry_map(%d):unsupported interface for"
                                             " name=%u\n",c->so,m->req[0],name);
    r=LWL_ERR;
  }
  return r;
}
